// LPSaveBitampGDIPlusDll6.cpp : Defines the entry point for the DLL application.
//

//#include "stdafx.h"
#include "windows.h"
#include "gdiplus.h"
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;

#include "LPSaveBitampGDIPlusDll6.h"

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

/*
// This is an example of an exported variable
LPSAVEBITAMPGDIPLUSDLL6_API int nLPSaveBitampGDIPlusDll6=0;

// This is an example of an exported function.
LPSAVEBITAMPGDIPLUSDLL6_API int fnLPSaveBitampGDIPlusDll6(void)
{
	return 42;
}

// This is the constructor of a class that has been exported.
// see LPSaveBitampGDIPlusDll6.h for the class definition
CLPSaveBitampGDIPlusDll6::CLPSaveBitampGDIPlusDll6()
{ 
	return; 
}

*/


//Copied from MSDN
//Helper function to get encoder parameters
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
   UINT  num = 0;          // number of image encoders
   UINT  size = 0;         // size of the image encoder array in bytes

   ImageCodecInfo* pImageCodecInfo = NULL;

   GetImageEncodersSize(&num, &size);
   if(size == 0)
      return -1;  // Failure

   pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
   if(pImageCodecInfo == NULL)
      return -1;  // Failure

   GetImageEncoders(num, size, pImageCodecInfo);

   for(UINT j = 0; j < num; ++j)
   {
      if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
      {
         *pClsid = pImageCodecInfo[j].Clsid;
         free(pImageCodecInfo);
         return j;  // Success
      }    
   }

   free(pImageCodecInfo);
   return -1;  // Failure
}

LPSAVEBITAMPGDIPLUSDLL6_API int LPSaveBitmapGDIPlusLib_SaveJPG(HBITMAP hBmp, LPCWSTR lpcwfilename){
	int ret=0;
		
	ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	Bitmap* bmp=new Bitmap(hBmp,NULL);

	//GpBitmap* pbmp;
	//GdipCreateBitmapFromHBITMAP(hbmp, NULL, &pbmp); //identifier not found!!

	CLSID jpgClsid;
	if (GetEncoderClsid(L"image/jpeg", &jpgClsid) == -1) return -1; //error
	
	ULONG uQuality=90;

	EncoderParameters encoderParams;
    encoderParams.Count = 1;
    encoderParams.Parameter[0].NumberOfValues = 1;
    encoderParams.Parameter[0].Guid  = EncoderQuality;
    encoderParams.Parameter[0].Type  = EncoderParameterValueTypeLong;
    encoderParams.Parameter[0].Value = &uQuality;
	
	
	//Save to disk
	//GdipSaveImageToFile(pbmp, lpcwfilename, &jpgClsid, &encoderParams);
	//GdipSaveImageToFile(pbmp, lpcwfilename, &jpgClsid, NULL);
	ret=bmp->Save(lpcwfilename, &jpgClsid, &encoderParams);
	
	//clean up
	delete[] bmp;
	GdiplusShutdown(gdiplusToken);

	return ret; //ok
}

LPSAVEBITAMPGDIPLUSDLL6_API int LPSaveBitmapGDIPlusLib_SavePNG(HBITMAP hBmp, LPCWSTR lpszFilename){
	//This code works well in saving 32bit bitmaps with alpha

	ULONG_PTR gdiplusToken;
	int st=0;
	int w, h;
	long npixels;

	//Get size of bitmap
	
	//Doesn't work because GetBitmapDimensionEx only works if SetBitmapDimensionEx was used
	//SIZE bmpsize;
	//if (!GetBitmapDimensionEx(hBmp,&bmpsize)) return -1; //error if it fails
	//w=bmpsize.cx;
	//h=bmpsize.cy;
	
	BITMAP bm;
	GetObject(hBmp,sizeof(BITMAP),&bm);
	w=bm.bmWidth;
	h=bm.bmHeight;
	
	npixels=w*h;
	
	if (npixels==0) return -1;

	GdiplusStartupInput gdiplusStartupInput;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	
	Bitmap* bmp=NULL;	
	BYTE* lpbyte=NULL;
	try{
		if (bm.bmBitsPixel==32){
				//Contains alpha channel
				lpbyte=new BYTE[npixels*4];
				long l=GetBitmapBits(hBmp,npixels*4,lpbyte); //Gets bits from HBITMAP
				bmp=new Bitmap(w,h,w*4,PixelFormat32bppARGB,lpbyte);
		}else{
			bmp=new Bitmap(hBmp,NULL);
		}

		CLSID pngClsid;
		if (GetEncoderClsid(L"image/png", &pngClsid) == -1) return -1; //Failed to get encoder

		st=bmp->Save(lpszFilename, &pngClsid,NULL); //not working, giving invalid parameter
		

	}catch(char *e){
		//MessageBox(NULL,L"Exception",NULL,MB_OK);
		st=-1;
	}

	//Clean up
	if (bmp != NULL) delete[] bmp;
	if (lpbyte != NULL) delete[] lpbyte;
	GdiplusShutdown(gdiplusToken);

	return st;
}

